<template>
  <!-- 弹窗页面 -->
  <el-dialog :close-on-click-modal='false' v-drag :title="record.id?$t('编辑'):$t('添加')" :v-if="dialogFormVisible" :visible.sync="dialogFormVisible" width="650px" top="10vh" @close="close">
    <el-form :model="record" :rules="rules" :hide-required-asterisk="true" ref="form" label-position="left" style="width:550px;margin: 0 auto;">
      <el-form-item :label="$t('对象名称')" :label-width="formLabelWidth" prop="name" @input="updateView($event)" key="nameInput">
        <el-input id="server-tools-name" v-emoji size='small' v-model="record.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item :label="$t('描述')" :label-width="formLabelWidth" @input="updateView($event)">
        <el-input id="server-tools-desc" v-emoji type="textarea" @keydown.native="handleKeyCode($event)" :autosize="{ minRows: 3, maxRows: 5}" :placeholder="$t('请输入内容')" v-model="record.desc">
        </el-input>
      </el-form-item>
      <el-form-item :label="$t('协议')" :label-width="formLabelWidth" prop="cmd_type" @input="updateView($event)" key="cmd_type">
        <el-select :disabled="record.id ? true: false" v-model="record.cmd_type" size='small' filterable @change="cmdTypeChange" style="width:100%;">
          <el-option v-for="(item, index) in cmdTypeList" :key="item" :label="index" :value="item" :id="`server-tools-cmd_type-${item}`">
          </el-option>
        </el-select>
      </el-form-item>

      <!-- 类型页面-->
      <!-- TCP和UDP -->
      <div v-if="record.cmd_type === '2' || record.cmd_type === '3' || record.cmd_type === '4' || record.cmd_type === '5'">
        <el-form-item :label="$t('端口范围')" prop="ports" :label-width="formLabelWidth" @input="updateView($event)">
          <el-input id="server-tools-ports" v-emoji size='small' type="textarea" @keydown.native="handleKeyCode($event)" :autosize="{ minRows: 3, maxRows: 5}" :placeholder="$t('可输入以,分割的多个散列端口或以-连接的端口范围，例如：1,3,5-7')" v-model="record.ports">
          </el-input>
        </el-form-item>
      </div>
      <!-- ICMP -->
      <div v-if="['1'].includes(record.cmd_type)">
        <el-form-item :label="$t('类型')" :label-width="formLabelWidth" prop="type" @input="updateView($event)">
          <el-input id="server-tools-type" v-emoji size='small' v-model="record.type" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item :label="$t('编码')" :label-width="formLabelWidth" prop="code" @input="updateView($event)">
          <el-input id="server-tools-code" v-emoji size='small' v-model="record.code" autocomplete="off"></el-input>
        </el-form-item>
      </div>
      <!-- ICMPv6 -->
      <div v-if="['7'].includes(record.cmd_type)">
        <el-form-item label="ICMPv6" :label-width="formLabelWidth" prop="pattern" @input="updateView($event)" v-if="record.cmd_type === '7'" key="nameCmdType">
          <el-select v-model="record.pattern" size='small' filterable @change="nameChange" style="width:100%;">
            <el-option v-for="(item,index) in icmpv6ListShow" :key="item" :label="patternShow[item] || item" :value="item" :id="`server-tools-pattern-${index}`">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('类型')" :label-width="formLabelWidth" prop="v6Type" @input="updateView($event)">
          <el-input id="server-tools-v6Type" v-emoji size='small' v-model="record.v6Type" autocomplete="off" :disabled='serviceIcmpv6Status'></el-input>
        </el-form-item>
        <el-form-item :label="$t('编码')" :label-width="formLabelWidth" prop="v6Code" @input="updateView($event)">
          <el-input id="server-tools-v6Code" v-emoji size='small' v-model="record.v6Code" autocomplete="off" :disabled='serviceIcmpv6Status'></el-input>
        </el-form-item>
      </div>
      <!-- 其他IP协议 -->
      <div v-if="record.cmd_type === '6'">
        <el-form-item :label="$t('协议号')" :label-width="formLabelWidth" prop="prot" @input="updateView($event)">
          <el-input id="server-tools-prot" v-emoji size='small' v-model="record.prot" autocomplete="off"></el-input>
        </el-form-item>
      </div>

    </el-form>
    <!-- 弹窗控件 -->
    <div slot="footer" class="dialog-footer">
      <el-button id="server-tools-child-form" type="primary" @click="handleChildForm">{{$t('确 定')}}</el-button>
      <el-button id="server-tools-close" @click="close">{{$t('取 消')}}</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { addServiceData, editServiceData, getServiceIcmpv6 } from '@/api/list/server'
export default {
  name: 'ServerTools',
  data () {
    var validateName = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入对象名称')))
      } else {
        callback()
      }
    }
    var validatePorts = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      let msg = ''
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入端口范围')))
      } else {
        let spValue = value.split(',')
        for (let item of spValue) {
          if (item.indexOf('-') > -1) {
            let spItem = item.split('-')
            for (let spVa of spItem) {
              msg = this.rulePost(spVa, zhStr) ? this.rulePost(spVa, zhStr) : msg
            }
          } else {
            msg = this.rulePost(item, zhStr) ? this.rulePost(item, zhStr) : msg
          }
        }
        if (msg) {
          callback(new Error(msg))
        } else {
          callback()
        }
      }
    }
    var validateType = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入ICMP类型')))
      } else if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        callback(new Error(this.$t('不能输入中文')))
      } else {
        callback()
      }
    }
    var validateCode = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入ICMP编码')))
      } else if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        callback(new Error(this.$t('不能输入中文')))
      } else {
        callback()
      }
    }
    var validateV6Type = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入ICMPv6类型')))
      } else if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        callback(new Error(this.$t('不能输入中文')))
      } else {
        callback()
      }
    }
    var validateV6Code = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入ICMPv6编码')))
      } else if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        callback(new Error(this.$t('不能输入中文')))
      } else {
        callback()
      }
    }
    var validateProt = (rule, value, callback) => {
      let zhStr = /[^\u4E00-\u9FA5]/g
      if (!String(value).trim()) {
        callback(new Error(this.$t('请输入协议号')))
      } else if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        callback(new Error(this.$t('不能输入中文')))
      } else {
        callback()
      }
    }
    return {
      dialogFormVisible: false,
      visible: false,
      old_name: '',
      old_desc: '',
      icmpv6List: {},
      icmpv6ListShow: [],
      serviceIcmpv6Status: false,
      record: {
        id: null,
        cmd_type: '2',
        pattern: 'default',
        name: '',
        desc: '',
        ports: '',
        type: '',
        v6Type: '',
        code: '',
        v6Code: '',
        prot: ''
      },
      recordCopy: {
        id: null,
        cmd_type: '2',
        pattern: 'default',
        name: '',
        desc: '',
        ports: '',
        type: '',
        v6Type: '',
        code: '',
        v6Code: '',
        prot: ''
      },
      patternShow: {'default': this.$t('用户自定义')},
      cmdTypeList: {
        'TCP': '2',
        'UDP': '3',
        'DCCP': '4',
        'SCTP': '5',
        'ICMP': '1',
        'ICMPv6': '7',
        [this.$t('其他IP协议')]: '6'
      },
      rules: {
        name: [{ required: false, validator: validateName, trigger: 'blur' }],
        ports: [{ required: false, validator: validatePorts, trigger: 'blur' }],
        type: [{ required: false, validator: validateType, trigger: 'blur' }],
        v6Type: [{ required: false, validator: validateV6Type, trigger: 'blur' }],
        code: [{ required: false, validator: validateCode, trigger: 'blur' }],
        v6Code: [{ required: false, validator: validateV6Code, trigger: 'blur' }],
        prot: [{ required: false, validator: validateProt, trigger: 'blur' }]
      },
      formLabelWidth: '100px'
    }
  },
  watch: {
    'record.desc': {
      handler (newVal) {
        this.record.desc = newVal.replace(/[\r\n]/g, '')
      },
      immediate: true
    },
    'record.ports': {
      handler (newVal) {
        this.record.ports = newVal.replace(/[\r\n]/g, '')
      },
      immediate: true
    }
  },
  methods: {
    init (data) {
      this.dialogFormVisible = true
      getServiceIcmpv6().then(res => {
        this.icmpv6List = res.info
        this.icmpv6ListShow = ['default']
        for (let item in this.icmpv6List) {
          this.icmpv6ListShow.push(item)
        }
        if (data) {
          this.record = Object.assign(this.record, data)
          this.record.cmd_type = String(this.record.cmd_type)
          this.old_name = data.name
          this.old_desc = data.desc
          if (this.record.cmd_type === '7') {
            this.record['v6Code'] = data.code
            this.record['v6Type'] = data.type
            this.serviceIcmpv6Status = !!this.icmpv6List[this.record.pattern]
          }
        }
      })
    },
    cmdTypeChange (val) {
      this.$refs.form.clearValidate(['ports', 'type', 'code', 'prot'])
    },
    nameChange (data) {
      this.serviceIcmpv6Status = !!this.icmpv6List[data]
      if (this.serviceIcmpv6Status) {
        this.record.v6Type = this.icmpv6List[data].ucType
        this.record.v6Code = this.icmpv6List[data].ucCode
        this.$refs.form.validateField(['v6Code', 'v6Type'])
      } else {
        this.record.v6Type = ''
        this.record.v6Code = ''
        this.$refs.form.clearValidate(['v6Code', 'v6Type'])
      }
    },
    handleChildForm (data) {
      this.$refs.form.validate((valid) => {
        if (valid) {
          let childForm = Object.assign({}, this.record)
          if (childForm.cmd_type === '7') {
            childForm.type = childForm.v6Type
            childForm.code = childForm.v6Code
            delete childForm.v6Type
            delete childForm.v6Code
          }
          if (!this.record.id) {
            addServiceData(childForm).then(response => {
              if (response.status === 0) {
                this.$messages.success(this.$t('添加成功'))
                this.$emit('listData')
                this.close()
              }
            })
          } else {
            childForm.old_name = this.old_name
            childForm.old_desc = this.old_desc
            editServiceData(childForm).then(response => {
              if (response.status === 0) {
                this.$messages.success(this.$t('编辑成功'))
                this.$emit('listData')
                this.close()
              }
            })
          }
        }
      })
    },
    close () {
      this.dialogFormVisible = false
      this.record = Object.assign({}, this.recordCopy)
      this.serviceIcmpv6Status = false
      this.old_name = ''
      this.old_desc = ''
      this.icmpv6List = {}
      this.icmpv6ListShow = []
      this.$refs.form.resetFields()
    },
    handleKeyCode (event) {
      if (event.keyCode === 13) {
        event.preventDefault() // 阻止浏览器默认换行操作
        return false
      }
    },
    rulePost (value, zhStr) {
      if (!String(value).match(zhStr) || (String(value).match(zhStr).length !== String(value).length)) {
        return this.$t('不能输入中文')
      } else if (isNaN(Number(value))) {
        return this.$t('请输入数字')
      } else if (Number(value) > 65535 || Number(value) < 1) {
        return this.$t('端口的范围为1~65535')
      } else {
        return ''
      }
    },
    updateView (e) {
      this.$forceUpdate()
    }
  }
}
</script>

<style scoped>
.tools_box {
  text-align: left;
}
</style>
